<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>socket.io</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            font-family: sans-serif;
        }
        .chat-box {
            width: 960px;
            height: 70vh;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 99;
            background-color: #444;
            border-radius: 4px;
            overflow: hidden;
        }
        .chat-input {
            width: 100%;
            height: 50px;
            border: none;
            outline: none;
            padding: 0 5px;
            font-size: 16px;
            color: #fff;
            background-color: #666;
        }
    </style>
</head>
<body>
    <div id="app" class="w-[100vw] h-[100vh] bg-[#333]">
        <div class="chat-box flex">
            <div class="flex-1 flex flex-col bg-[#fff] w-[0px]">
                <div class="flex-1 h-[0px] overflow-y-auto">
                    <template v-for="(chat, index) in messageList" key="index">
                        <div :class="[{'text-right': userId == chat.userId}, 'p-[5px]']">
                            <div class="text-[#666]">{{ chat.userName}}</div>
                            <div>{{ chat.message }}</div> 
                         </div>
                    </template>
                </div>
                <div class="chat-input">
                    <input type="text" @keydown.enter="sendMessage" v-model="message" class="chat-input" placeholder="请输入消息，按回车键发送" />
                </div>
            </div>
            <div class="w-[200px] overflow-y-auto">
                <div @click="changeChatType(user.userId)" v-for="user in userList" :key="user.userId" :class="['cursor-pointer border-b border-[#333] flex items-center p-[5px] pl-[10px] text-[#fff] justify-between', {'bg-[#fff] text-[#333]': chatUserId.includes(user.userId)}]">
                    <div>{{ user.userName }}</div>
                    <div class="text-[12px]" v-if="userId == user.userId">自己</div>
                    <div class="text-[12px]" v-else="userId != user.userId">
                        {{ chatUserId.includes(user.userId) ? '点击取消' : '点击单聊' }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    const { createApp, ref } = Vue
    createApp({
      setup() {
        const userId = ref(Math.floor(Math.random() * 10000))
        const chatUserId = ref([])
        const userName = '用户' + userId.value
        const messageList = ref([])
        const userList = ref([])
        const socket = io('http://192.168.137.130:8000', {
            query: {
                userId: userId.value,
                userName
            }
        })
        socket.on('connection', ()=> {
            console.log('连接成功')
        })
        socket.on('disconnect', ()=> {
            console.log('断开连接')
        })
        socket.on('message', (data) => {
            if (data.type === 'userList') {
                userList.value = [{userId, userName}].concat(data.message.filter(user => user.userId != userId.value))
            } else if (data.type === 'addUser') { 
                userList.value.push(data.message)
            } else if (data.type === 'delUser') {
                userList.value = userList.value.filter(item => item.userId != data.message.userId)
            } else if (data.type === 'chatMessage') {
                messageList.value.push(data.message)
            }
        })
        const message = ref('')
        // 切换单聊多聊和群聊
        const changeChatType = (id) => {
            if(id == userId.value) return
            if(chatUserId.value.includes(id)) {
                chatUserId.value = chatUserId.value.filter(item => item!= id)
            } else {
                chatUserId.value.push(id)
            }
        }
        // 发送消息
        const sendMessage = () => {
            if (!message.value) return
            const messageInfo = {
                userId: userId.value,
                userName: userName,
                message: message.value,
                toUserId: chatUserId.value
            }
            messageList.value.push(messageInfo)
            socket.emit('message', {
                type: chatUserId.value.length > 0 ? 'singleMessage' : 'chatMessage',
                message: messageInfo
            })
            message.value = ''
        }
        return {
          message,
          userList,
          userId,
          messageList,
          sendMessage,
          chatUserId,
          changeChatType
        }
      }
    }).mount('#app')
  </script>
</html>